//+------------------------------------------------------------------+
//|                                    SupportResistanceSystem.mqh |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property link      ""
#property version   "1.00"
#property strict

// 支撑阻力位类型枚举
enum ENUM_LEVEL_TYPE {
    LEVEL_SUPPORT,           // 支撑位
    LEVEL_RESISTANCE,        // 阻力位
    LEVEL_PIVOT,            // 轴心位
    LEVEL_FIBONACCI,        // 斐波那契位
    LEVEL_WAVE_LEVEL        // 波浪位
};

// 支撑阻力位强度枚举
enum ENUM_LEVEL_STRENGTH {
    LEVEL_STRENGTH_WEAK,     // 弱
    LEVEL_STRENGTH_MEDIUM,   // 中等
    LEVEL_STRENGTH_STRONG,   // 强
    LEVEL_STRENGTH_CRITICAL  // 关键
};

// 支撑阻力位结构
struct PriceLevel {
    ENUM_LEVEL_TYPE type;        // 位类型
    ENUM_LEVEL_STRENGTH strength; // 强度
    double price;                // 价格水平
    datetime time;               // 形成时间
    int barIndex;                // K线索引
    int touchCount;              // 触及次数
    datetime lastTouch;          // 最后触及时间
    bool isActive;               // 是否活跃
    double volume;               // 成交量
    string description;          // 描述
};

// 支撑阻力位分析类
class CSupportResistanceAnalysis {
private:
    PriceLevel m_levels[];       // 支撑阻力位数组
    int m_levelCount;            // 位数量
    
    // 分析参数
    int m_lookbackPeriod;        // 回看周期
    int m_minTouchCount;         // 最小触及次数
    double m_tolerance;          // 容差
    int m_fibonacciPeriods[];    // 斐波那契周期
    double m_pivotPeriod;        // 轴心位周期
    
    // 波浪相关
    double m_wave2Retracement;   // 第2浪回撤
    double m_wave4Retracement;   // 第4浪回撤
    double m_wave3Extension;     // 第3浪延伸
    
public:
    // 构造函数
    CSupportResistanceAnalysis() {
        m_levelCount = 0;
        m_lookbackPeriod = 100;      // 默认回看100根K线
        m_minTouchCount = 2;         // 最少触及2次
        m_tolerance = 0.001;         // 0.1%容差
        m_wave2Retracement = 0.618;  // 第2浪回撤61.8%
        m_wave4Retracement = 0.382;  // 第4浪回撤38.2%
        m_wave3Extension = 1.618;    // 第3浪延伸161.8%
        
        // 初始化斐波那契周期
        ArrayResize(m_fibonacciPeriods, 5);
        m_fibonacciPeriods[0] = 20;  // 短期
        m_fibonacciPeriods[1] = 50;  // 中期
        m_fibonacciPeriods[2] = 100; // 长期
        m_fibonacciPeriods[3] = 200; // 超长期
        m_fibonacciPeriods[4] = 500; // 极长期
        
        m_pivotPeriod = 20;          // 轴心位周期
    }
    
    // 初始化
    bool Initialize(int lookbackPeriod = 100, int minTouchCount = 2, 
                   double tolerance = 0.001) {
        m_lookbackPeriod = lookbackPeriod;
        m_minTouchCount = minTouchCount;
        m_tolerance = tolerance;
        return true;
    }
    
    // 分析支撑阻力位
    bool AnalyzeSupportResistance(const double &high[], const double &low[], 
                                 const double &close[], const double &volume[], int count) {
        if(count < m_lookbackPeriod) return false;
        
        // 重置支撑阻力位数组
        ArrayResize(m_levels, 0);
        m_levelCount = 0;
        
        // 1. 识别价格轴心位
        IdentifyPivotLevels(high, low, close, volume, count);
        
        // 2. 识别斐波那契回撤位
        IdentifyFibonacciLevels(high, low, close, count);
        
        // 3. 识别波浪理论位
        IdentifyWaveLevels(high, low, close, count);
        
        // 4. 识别历史支撑阻力位
        IdentifyHistoricalLevels(high, low, close, volume, count);
        
        // 5. 验证和合并重复位
        ValidateAndMergeLevels();
        
        return m_levelCount > 0;
    }
    
    // 识别价格轴心位
    void IdentifyPivotLevels(const double &high[], const double &low[], 
                            const double &close[], const double &volume[], int count) {
        for(int idx = m_pivotPeriod; idx < count - m_pivotPeriod; idx++) {
            // 检查是否为局部高点（阻力位）
            if(IsLocalHigh(high, idx, m_pivotPeriod)) {
                PriceLevel level;
                level.type = LEVEL_RESISTANCE;
                level.price = high[idx];
                level.time = TimeCurrent();
                level.barIndex = idx;
                level.touchCount = 1;
                level.lastTouch = level.time;
                level.isActive = true;
                level.volume = volume[idx];
                level.strength = CalculateLevelStrength(volume[idx], m_pivotPeriod);
                level.description = "Pivot Resistance";
                
                AddLevel(level);
            }
            
            // 检查是否为局部低点（支撑位）
            if(IsLocalLow(low, idx, m_pivotPeriod)) {
                PriceLevel level;
                level.type = LEVEL_SUPPORT;
                level.price = low[idx];
                level.time = TimeCurrent();
                level.barIndex = idx;
                level.touchCount = 1;
                level.lastTouch = level.time;
                level.isActive = true;
                level.volume = volume[idx];
                level.strength = CalculateLevelStrength(volume[idx], m_pivotPeriod);
                level.description = "Pivot Support";
                
                AddLevel(level);
            }
        }
    }
    
    // 识别斐波那契回撤位
    void IdentifyFibonacciLevels(const double &high[], const double &low[], 
                                const double &close[], int count) {
        double fibLevels[] = {0.236, 0.382, 0.500, 0.618, 0.786};
        
        for(int period : m_fibonacciPeriods) {
            if(count < period * 2) continue;
            
            // 寻找主要趋势
            double swingHigh = FindSwingHigh(high, count - period, count);
            double swingLow = FindSwingLow(low, count - period, count);
            
            if(swingHigh > 0 && swingLow > 0) {
                double range = swingHigh - swingLow;
                
                // 计算斐波那契位
                for(double fib : fibLevels) {
                    double level = swingHigh - (range * fib);
                    
                    PriceLevel priceLevel;
                    priceLevel.type = (fib <= 0.5) ? LEVEL_RESISTANCE : LEVEL_SUPPORT;
                    priceLevel.price = level;
                    priceLevel.time = TimeCurrent();
                    priceLevel.barIndex = count - 1;
                    priceLevel.touchCount = 1;
                    priceLevel.lastTouch = priceLevel.time;
                    priceLevel.isActive = true;
                    priceLevel.volume = 0;
                    priceLevel.strength = LEVEL_STRENGTH_MEDIUM;
                    priceLevel.description = "Fibonacci " + DoubleToString(fib * 100, 1) + "%";
                    
                    AddLevel(priceLevel);
                }
            }
        }
    }
    
    // 识别波浪理论位
    void IdentifyWaveLevels(const double &high[], const double &low[], 
                           const double &close[], int count) {
        // 基于五浪理论识别关键位
        if(count < 50) return;
        
        // 寻找潜在的波浪结构
        for(int idx = 20; idx < count - 20; idx++) {
            // 第2浪回撤位（支撑位）
            if(IsWave2Retracement(high, low, close, idx)) {
                double wave1High = FindWave1High(high, idx - 20, idx);
                double wave1Low = FindWave1Low(low, idx - 20, idx);
                
                if(wave1High > 0 && wave1Low > 0) {
                    double retracementLevel = wave1High - ((wave1High - wave1Low) * m_wave2Retracement);
                    
                    PriceLevel level;
                    level.type = LEVEL_SUPPORT;
                    level.price = retracementLevel;
                    level.time = TimeCurrent();
                    level.barIndex = idx;
                    level.touchCount = 1;
                    level.lastTouch = level.time;
                    level.isActive = true;
                    level.volume = 0;
                    level.strength = LEVEL_STRENGTH_STRONG;
                    level.description = "Wave 2 Retracement";
                    
                    AddLevel(level);
                }
            }
            
            // 第4浪回撤位（支撑位）
            if(IsWave4Retracement(high, low, close, idx)) {
                double wave3High = FindWave3High(high, idx - 20, idx);
                double wave3Low = FindWave3Low(low, idx - 20, idx);
                
                if(wave3High > 0 && wave3Low > 0) {
                    double retracementLevel = wave3High - ((wave3High - wave3Low) * m_wave4Retracement);
                    
                    PriceLevel level;
                    level.type = LEVEL_SUPPORT;
                    level.price = retracementLevel;
                    level.time = TimeCurrent();
                    level.barIndex = idx;
                    level.touchCount = 1;
                    level.lastTouch = level.time;
                    level.isActive = true;
                    level.volume = 0;
                    level.strength = LEVEL_STRENGTH_STRONG;
                    level.description = "Wave 4 Retracement";
                    
                    AddLevel(level);
                }
            }
        }
    }
    
    // 识别历史支撑阻力位
    void IdentifyHistoricalLevels(const double &high[], const double &low[], 
                                 const double &close[], const double &volume[], int count) {
        // 分析历史价格行为识别重要位
        for(int idx = 10; idx < count - 10; idx++) {
            // 检查是否有多次触及同一价格水平
            double currentPrice = close[idx];
            
            for(int jdx = 0; jdx < m_levelCount; jdx++) {
                if(MathAbs(currentPrice - m_levels[jdx].price) <= m_tolerance * currentPrice) {
                    m_levels[jdx].touchCount++;
                    m_levels[jdx].lastTouch = TimeCurrent();
                    
                    // 根据触及次数提升强度
                    if(m_levels[jdx].touchCount >= 3) {
                        m_levels[jdx].strength = LEVEL_STRENGTH_STRONG;
                    }
                    if(m_levels[jdx].touchCount >= 5) {
                        m_levels[jdx].strength = LEVEL_STRENGTH_CRITICAL;
                    }
                }
            }
        }
    }
    
    // 验证和合并重复位
    void ValidateAndMergeLevels() {
        // 移除触及次数不足的位
        for(int idx = m_levelCount - 1; idx >= 0; idx--) {
            if(m_levels[idx].touchCount < m_minTouchCount) {
                RemoveLevel(idx);
            }
        }
        
        // 合并相近的位
        for(int idx = 0; idx < m_levelCount - 1; idx++) {
            for(int jdx = idx + 1; jdx < m_levelCount; jdx++) {
                if(MathAbs(m_levels[idx].price - m_levels[jdx].price) <= m_tolerance * m_levels[idx].price) {
                    // 合并两个位
                    MergeLevels(idx, jdx);
                    jdx--; // 重新检查当前位置
                }
            }
        }
    }
    
    // 检查价格是否接近支撑阻力位
    bool IsNearLevel(double price, ENUM_LEVEL_TYPE type, double tolerance = 0.002) {
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].type == type && m_levels[idx].isActive) {
                if(MathAbs(price - m_levels[idx].price) <= tolerance * price) {
                    return true;
                }
            }
        }
        return false;
    }
    
    // 获取最近的支撑位
    bool GetNearestSupport(double price, PriceLevel &level) {
        double minDistance = DBL_MAX;
        int nearestIndex = -1;
        
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].type == LEVEL_SUPPORT && m_levels[idx].isActive && 
               m_levels[idx].price < price) {
                double distance = price - m_levels[idx].price;
                if(distance < minDistance) {
                    minDistance = distance;
                    nearestIndex = idx;
                }
            }
        }
        
        if(nearestIndex >= 0) {
            level = m_levels[nearestIndex];
            return true;
        }
        
        return false;
    }
    
    // 获取最近的阻力位
    bool GetNearestResistance(double price, PriceLevel &level) {
        double minDistance = DBL_MAX;
        int nearestIndex = -1;
        
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].type == LEVEL_RESISTANCE && m_levels[idx].isActive && 
               m_levels[idx].price > price) {
                double distance = m_levels[idx].price - price;
                if(distance < minDistance) {
                    minDistance = distance;
                    nearestIndex = idx;
                }
            }
        }
        
        if(nearestIndex >= 0) {
            level = m_levels[nearestIndex];
            return true;
        }
        
        return false;
    }
    
    // 检查支撑阻力位突破
    bool IsLevelBreakout(double currentPrice, double previousPrice, ENUM_LEVEL_TYPE type) {
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].type == type && m_levels[idx].isActive) {
                double levelPrice = m_levels[idx].price;
                
                if(type == LEVEL_RESISTANCE) {
                    // 向上突破阻力位
                    if(previousPrice <= levelPrice && currentPrice > levelPrice) {
                        return true;
                    }
                } else if(type == LEVEL_SUPPORT) {
                    // 向下突破支撑位
                    if(previousPrice >= levelPrice && currentPrice < levelPrice) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    // 检查支撑阻力位回踩确认
    bool IsLevelRetest(double currentPrice, double breakoutPrice, ENUM_LEVEL_TYPE type) {
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].type == type && m_levels[idx].isActive) {
                double levelPrice = m_levels[idx].price;
                
                if(type == LEVEL_RESISTANCE) {
                    // 阻力位突破后回踩确认
                    if(breakoutPrice > levelPrice && 
                       MathAbs(currentPrice - levelPrice) <= m_tolerance * levelPrice) {
                        return true;
                    }
                } else if(type == LEVEL_SUPPORT) {
                    // 支撑位突破后回踩确认
                    if(breakoutPrice < levelPrice && 
                       MathAbs(currentPrice - levelPrice) <= m_tolerance * levelPrice) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    // 获取所有活跃的支撑阻力位
    int GetActiveLevels(PriceLevel &levels[]) {
        int activeCount = 0;
        ArrayResize(levels, 0);
        
        for(int idx = 0; idx < m_levelCount; idx++) {
            if(m_levels[idx].isActive) {
                ArrayResize(levels, activeCount + 1);
                levels[activeCount++] = m_levels[idx];
            }
        }
        
        return activeCount;
    }
    
    // 获取位数量
    int GetLevelCount() {
        return m_levelCount;
    }
    
private:
    // 检查是否为局部高点
    bool IsLocalHigh(const double &high[], int index, int period) {
        double currentHigh = high[index];
        
        for(int idx = index - period; idx <= index + period; idx++) {
            if(idx != index && high[idx] >= currentHigh) {
                return false;
            }
        }
        return true;
    }
    
    // 检查是否为局部低点
    bool IsLocalLow(const double &low[], int index, int period) {
        double currentLow = low[index];
        
        for(int idx = index - period; idx <= index + period; idx++) {
            if(idx != index && low[idx] <= currentLow) {
                return false;
            }
        }
        return true;
    }
    
    // 计算位强度
    ENUM_LEVEL_STRENGTH CalculateLevelStrength(double volume, int period) {
        // 基于成交量和时间计算强度
        if(volume > period * 2) return LEVEL_STRENGTH_CRITICAL;
        if(volume > period * 1.5) return LEVEL_STRENGTH_STRONG;
        if(volume > period) return LEVEL_STRENGTH_MEDIUM;
        return LEVEL_STRENGTH_WEAK;
    }
    
    // 寻找摆动高点
    double FindSwingHigh(const double &high[], int start, int end) {
        double maxHigh = 0;
        for(int idx = start; idx < end; idx++) {
            if(high[idx] > maxHigh) {
                maxHigh = high[idx];
            }
        }
        return maxHigh;
    }
    
    // 寻找摆动低点
    double FindSwingLow(const double &low[], int start, int end) {
        double minLow = DBL_MAX;
        for(int idx = start; idx < end; idx++) {
            if(low[idx] < minLow) {
                minLow = low[idx];
            }
        }
        return (minLow == DBL_MAX) ? 0 : minLow;
    }
    
    // 检查是否为第2浪回撤
    bool IsWave2Retracement(const double &high[], const double &low[], 
                           const double &close[], int index) {
        // 简化的第2浪识别逻辑
        if(index < 10) return false;
        
        // 检查是否在上升趋势中出现回调
        bool wasUpTrend = true;
        for(int idx = index - 5; idx < index; idx++) {
            if(close[idx] <= close[idx - 1]) {
                wasUpTrend = false;
                break;
            }
        }
        
        return wasUpTrend && (close[index] < close[index - 1]);
    }
    
    // 检查是否为第4浪回撤
    bool IsWave4Retracement(const double &high[], const double &low[], 
                           const double &close[], int index) {
        // 简化的第4浪识别逻辑
        if(index < 15) return false;
        
        // 检查是否在上升趋势中出现回调
        bool wasUpTrend = true;
        for(int idx = index - 10; idx < index; idx++) {
            if(close[idx] <= close[idx - 1]) {
                wasUpTrend = false;
                break;
            }
        }
        
        return wasUpTrend && (close[index] < close[index - 1]);
    }
    
    // 寻找第1浪高点
    double FindWave1High(const double &high[], int start, int end) {
        return FindSwingHigh(high, start, end);
    }
    
    // 寻找第1浪低点
    double FindWave1Low(const double &low[], int start, int end) {
        return FindSwingLow(low, start, end);
    }
    
    // 寻找第3浪高点
    double FindWave3High(const double &high[], int start, int end) {
        return FindSwingHigh(high, start, end);
    }
    
    // 寻找第3浪低点
    double FindWave3Low(const double &low[], int start, int end) {
        return FindSwingLow(low, start, end);
    }
    
    // 添加支撑阻力位
    void AddLevel(PriceLevel &level) {
        ArrayResize(m_levels, m_levelCount + 1);
        m_levels[m_levelCount++] = level;
    }
    
    // 移除支撑阻力位
    void RemoveLevel(int index) {
        if(index < 0 || index >= m_levelCount) return;
        
        for(int idx = index; idx < m_levelCount - 1; idx++) {
            m_levels[idx] = m_levels[idx + 1];
        }
        m_levelCount--;
    }
    
    // 合并两个支撑阻力位
    void MergeLevels(int index1, int index2) {
        if(index1 < 0 || index1 >= m_levelCount || 
           index2 < 0 || index2 >= m_levelCount || index1 == index2) return;
        
        // 合并价格（加权平均）
        double totalVolume = m_levels[index1].volume + m_levels[index2].volume;
        if(totalVolume > 0) {
            m_levels[index1].price = (m_levels[index1].price * m_levels[index1].volume + 
                                     m_levels[index2].price * m_levels[index2].volume) / totalVolume;
        } else {
            m_levels[index1].price = (m_levels[index1].price + m_levels[index2].price) / 2.0;
        }
        
        // 合并其他属性
        m_levels[index1].touchCount += m_levels[index2].touchCount;
        m_levels[index1].volume = totalVolume;
        
        // 选择更强的强度
        if(m_levels[index2].strength > m_levels[index1].strength) {
            m_levels[index1].strength = m_levels[index2].strength;
        }
        
        // 移除第二个位
        RemoveLevel(index2);
    }
}; 